package com.fulihui.systemcore.biz.shard.impl;

import com.fulihui.systemcore.biz.shard.WechatTokenManager;
import com.fulihui.systemcore.dal.dataobj.WechatToken;
import com.fulihui.systemcore.dal.mapper.WechatTokenMapper;
import com.fulihui.systemcore.enums.WechatTokenTypeEnum;
import com.fulihui.weixinclient.WeixinClient;
import com.fulihui.weixinclient.request.AccessTokenWeixinRequest;
import com.fulihui.weixinclient.request.JsapiTicketWeixinRequest;
import com.fulihui.weixinclient.result.AccessTokenWeixinResult;
import com.fulihui.weixinclient.result.JsapiTicketWeixinResult;
import com.fulihui.weixinclient.util.WechatResultUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @author Willard.Hu on 2016/3/5.
 */
@Component
public class WechatTokenManagerImpl implements WechatTokenManager {
    private static final Logger LOG = LoggerFactory.getLogger(WechatTokenManagerImpl.class);
    /**
     * 锁超时时间
     */
    private static final int LOCK_TIMEOUT = 5;
    /**
     * 锁等待时间
     */
    private static final int LOCK_WAIT_TIMEOUT = 3;
    /**
     * 锁名称
     */
    private static final String LOCK_NAME = "wechat.token.create.lock";

    @Autowired
    private WechatTokenMapper wechatTokenMapper;
    @Autowired
    private WeixinClient weixinClient;

    @Override
    public String getToken(String appid, String secret, WechatTokenTypeEnum type) {
        WechatToken wechatToken = wechatTokenMapper.queryToken(appid, type.getCode());
        if (wechatToken == null) {
            try {
                wechatToken = wechatTokenMapper.queryToken(appid, type.getCode());
                if (wechatToken == null) {
                    LOG.debug("appid:{},type:{} 在数据空中没有找到凭证，开始从微信获取凭证并且插入到数据库", appid,
                            type.getCode());
                    wechatToken = queryRemote(appid, secret, type);
                    wechatTokenMapper.insert(wechatToken);
                    return wechatToken.getToken();
                }
            } finally {
            }
        }
        return wechatToken.getToken();
    }

    @Override
    public WechatToken queryRemote(String appid, String secret, WechatTokenTypeEnum type) {
        WechatToken wechatToken;
        if (type == WechatTokenTypeEnum.ACCESS_TOKEN) {
            AccessTokenWeixinRequest request = new AccessTokenWeixinRequest();
            request.setAppid(appid);
            request.setSecret(secret);
            AccessTokenWeixinResult result = weixinClient.invokeService(request);
            WechatResultUtil.checkResult(result);

            wechatToken = new WechatToken();
            wechatToken.setAppid(appid);
            wechatToken.setSecret(secret);
            wechatToken.setToken(result.getAccess_token());
            wechatToken.setExpiresIn(result.getExpires_in());
            wechatToken.setTokenType(type.getCode());
        } else if (type == WechatTokenTypeEnum.JS_API_TICKET) {
            String accessToken = getToken(appid, secret, WechatTokenTypeEnum.ACCESS_TOKEN);
            JsapiTicketWeixinRequest request = new JsapiTicketWeixinRequest();
            request.setAccess_token(accessToken);
            JsapiTicketWeixinResult result = weixinClient.invokeService(request);
            WechatResultUtil.checkResult(result);

            wechatToken = new WechatToken();
            wechatToken.setAppid(appid);
            wechatToken.setSecret(secret);
            wechatToken.setToken(result.getTicket());
            wechatToken.setExpiresIn(result.getExpires_in());
            wechatToken.setTokenType(type.getCode());
        } else {
            throw new UnsupportedOperationException("不支持的微信认证类型" + type.getCode());
        }
        return wechatToken;
    }
}
